知识点扫盲:

  • 对于x86_64-unknown-linux-gnu这样一个target triple(三元组)<架构>-<供应商>-<操作系统>-,unknown就是表示generic,常用的vendor有 pc, apple, or w64,
  • 需要注意的地方

    1. 使用osxcross制作macosx的交叉编译工具时,需要注意编译cctools-port时会报undefined symbol: _Unwind_Resume,原因是没有链接llvm的unwind库,使用LIBS环境变量解决
    2. 交叉编译macosx二进制时,只能使用https://github.com/tpoechtrager/cctools-port提供的链接工具,gnu binutils和llvm的链接器都没法完成链接(lld,gold,bfd)
    3. llvm/clang天然支持交叉编译,因此对于macosx平台,只需要osxcross提供的链接器和汇编器,其它的使用llvm提供的编译器和其它工具就好了,对于linux平台,可以使用全套llvm的工具集
    4. macosx提取的sdk头文件目录结构需要使用脚本手动修改,不能直接使用
    5. 不要尝试在x86_64系统下用llvm/clang交叉编译llvm/clang,巨艰难,最后在aws弄了个arm虚拟机编译了aarch64的clang
    6. 心得

      1. 即使对于本地平台,比如我本机是x86_64的ubuntu24.04,也建议使用x86_64的交叉编译工具这种方式来保证产出的二进制环境干净
      2. 交叉编译工具,一般不包含对应平台的sdk以及相应系统头文件,需要自己制作,对于mingw-w64要有多处改动,还需要改较多代码才能适配源码和系统,比如改了很多mingw-w64本身头文件,以及folly这些库才成功用mingw-w64交叉编译成功grpc,proxygen,folly,fbthrift等。强烈不建议使用mingw-w64来交叉编译,直接windows用bazel编译更香

      命令

      linux gcc交叉编译工具

      制作x86_64工具集

      macosx交叉编译工具和sdk

      git clone git@github.com:tpoechtrager/osxcross.git
      cd osxcross
      wget https://download.developer.apple.com/Developer_Tools/Xcode_15.2/Xcode_15.2.xip
      mv Xcode_15.2.xip tarballs
      ./tools/gen_sdk_package_pbzx.sh tarballs/Xcode_15.2.xip
      mv MacOSX14.sdk.tar.xz MacOSX14.2.sdk.tar.xz tarballs
      #macOS SDK Version: 14.2, Target: darwin23.2
      SDK_VERSION=14.2 OSX_VERSION_MIN=10.15 LIBS=-lunwind ./build.sh
      cd target/SDK/MacOSX14.2.sdk
      
      ./generate_library.sh
      
      

      generate_library.sh

      #!/bin/bash
      
      clean() {
        lib="${1%.framework}"
        if [ -d "${lib}" ]; then
            echo "now clean: ${lib}"
            rm -rf "${lib}"
        fi
      }
      
      
      process() {
        echo "now process: $1"
        lib="${1%.framework}"
        if [ ! -d "${lib}" ]; then
          mkdir -p "${lib}"
          if [ -d "$1/Headers" ]; then
            cp -r $1/Headers/* ${lib}
          fi
      
          if [ -d "$1/Modules" ]; then
            cp -r $1/Modules/* ${lib}
          fi
      
          if [ -d "$1/Contents" ]; then
            if [ -d "$1/Contents/Headers" ]; then
              cp -r $1/Contents/Headers/* ${lib}
            fi
            if [ -d "$1/Contents/Versions/Current/Headers" ]; then
              cp -r $1/Contents/Versions/Current/Headers/* ${lib}
            fi
          fi
      
          if ls "$1"/*.tbd >/dev/null 2>&1; then
            cp -L $1/*.tbd ${lib}
          fi
        else
          echo "${lib} already exists"
        fi
      }
      
      
      clean_dir() {
        for file in "$1"/*; do
          if [ -d "$file" ]; then
            if [[ "$file" == *.framework ]]; then
              clean $file
              continue
            fi
            clean_dir "$file"
          fi
        done
      }
      
      process_dir() {
        for file in "$1"/*; do
          if [ -d "$file" ]; then
            if [[ "$file" == *.framework ]]; then
              process $file
              continue
            fi
            process_dir "$file"
          fi
        done
      }
      
      #clean_dir System
      process_dir System
      
      

      llvm交叉编译工具制作

      1. 制作x86_64_unknown_linux_gnu工具集

        git checkout llvmorg-18.1.8
        cmake -G "Unix Makefiles" ../llvm \
            -DCMAKE_INSTALL_PREFIX=/usr/local/llvm/18 \
            -DCMAKE_BUILD_TYPE=Release \
            -DLLVM_ENABLE_PROJECTS="bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;polly;pstl;openmp" \
            -DLLVM_ENABLE_RUNTIMES="libc;libunwind;libcxxabi;libcxx" \
            -DCLANG_DEFAULT_CXX_STDLIB=libc++ \
            -DCLANG_DEFAULT_RTLIB=compiler-rt \
            -DCLANG_DEFAULT_LINKER=lld \
            -DMLIR_INCLUDE_INTEGRATION_TESTS=OFF \
            -DLLVM_INCLUDE_TESTS=OFF \
            -DLLVM_BUILD_TESTS=OFF \
            -DLLDB_INCLUDE_TESTS=OFF \
            -DCLANG_INCLUDE_TESTS=OFF
        make -j20
        
      2. 制作aarch64_unknown_linux_gnu工具集
        注意,需要找一台aarch64机器,使用x86_64交叉编译异常艰难

        
        git checkout llvmorg-18.1.8
        cmake -G "Unix Makefiles" ../llvm \
            -DCMAKE_INSTALL_PREFIX=/usr/local/llvm/18 \
            -DCMAKE_BUILD_TYPE=Release \
            -DLLVM_ENABLE_PROJECTS="bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;polly;pstl;openmp" \
            -DLLVM_ENABLE_RUNTIMES="libc;libunwind;libcxxabi;libcxx" \
            -DCLANG_DEFAULT_CXX_STDLIB=libc++ \
            -DCLANG_DEFAULT_RTLIB=compiler-rt \
            -DCLANG_DEFAULT_LINKER=lld \
            -DMLIR_INCLUDE_INTEGRATION_TESTS=OFF \
            -DLLVM_INCLUDE_TESTS=OFF \
            -DLLVM_BUILD_TESTS=OFF \
            -DLLDB_INCLUDE_TESTS=OFF \
            -DCLANG_INCLUDE_TESTS=OFF
        make -j20
        
      3. 制作x86_64_macos工具集

        
        
      4. 制作x86_64_macos工具集